package com.rational.serialization.json {

	import com.adobe.serialization.json.JSONEncoder;
	import flash.utils.ByteArray;

	public final class JSON {
		import cmodule.cson.CLibInit;

		private static const lib:* = new CLibInit().init();
		private static const decoder:Decoder = new Decoder();
		private static const typedDecoder:TypedDecoder = new TypedDecoder();
		private static const namespace:Namespace = new Namespace("cmodule.cson");
		private static const ram:ByteArray = (namespace::gstate).ds;
		private static const ref:Reference = new Reference();
		
		public static function decode(s:String, type:Class=null):* {
			const
				buffer:String = s + String.fromCharCode(0x00),
				length:int = s.length,
				ref:Reference = JSON.ref;
			switch (lib.compile(buffer, length, ref)) {
			case 0:
				try {
					return type ?
						typedDecoder.decode(ram, ref.referent, type) :
						decoder.decode(ram, ref.referent);
				} finally {
					lib.release(ref.referent);
				}
				break;
			case 1: throw new JSONError(ref.referent);
			case 2: throw new JSONError(ref.referent);
			default: throw new Error("fallthrough");
			}
		}
		
		public static function encode(o:*):String {
			return new JSONEncoder(o).getString();
		}
	}
}
